package com.shj.em.util;

import lombok.extern.slf4j.Slf4j;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

/**
 * @author Shen Huang Jian
 * @since 2018-09-28
 */
@Slf4j
public class PinYinHelper {

    /**
     * 将文字转为汉语拼音（小写）, 不是中文的字符将会被剔除
     * @param chinese 要转成拼音的中文
     */
    public static String toPurePinYinLow(String chinese){
        return toHanyuPinyin(chinese, HanyuPinyinCaseType.LOWERCASE).toLowerCase();
    }

    /**
     * 将文字转为汉语拼音（大写）, 不是中文的字符将会被剔除
     * @param chinese 要转成拼音的中文
     */
    public static String toPurePinYinUp(String chinese){
        return toHanyuPinyin(chinese, HanyuPinyinCaseType.UPPERCASE).toUpperCase();
    }

    private static String toHanyuPinyin(String chinese, HanyuPinyinCaseType caseType){
        if(StringUtils.isBlank(chinese)){
            return "";
        }
        char[] clChars = chinese.trim().toCharArray();
        String hanyupinyin = "";
        HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
        // 输出拼音全部小写
        defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        // 不带声调
        defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        defaultFormat.setVCharType(HanyuPinyinVCharType.WITH_V) ;
        try {
            for (int i=0; i<clChars.length; i++){
                // 如果字符是中文,则将中文转为汉语拼音
                if (String.valueOf(clChars[i]).matches("[\u4e00-\u9fa5]+")){
                    hanyupinyin += PinyinHelper.toHanyuPinyinStringArray(clChars[i], defaultFormat)[0];
                } else {
                    // 如果字符不是中文,则不转换
                    hanyupinyin += clChars[i];
                }
            }
        } catch (BadHanyuPinyinOutputFormatCombination e) {
            log.error("字符不能转成汉语拼音", e);
        }
        return hanyupinyin;
    }


    /**
     * 将文字转为汉语拼音（小写）, 不是中文的字符原样输出
     * @param chinese 要转成拼音的中文
     */
    public static String toPinYinLow(String chinese){
        return toPinYin(chinese, HanyuPinyinCaseType.LOWERCASE).toLowerCase();
    }

    /**
     * 将文字转为汉语拼音（大写）, 不是中文的字符原样输出
     * @param chinese 要转成拼音的中文
     */
    public static String toPinYinUp(String chinese){
        return toPinYin(chinese, HanyuPinyinCaseType.UPPERCASE).toUpperCase();
    }

    private static String toPinYin(String chinese, HanyuPinyinCaseType caseType){
        if(StringUtils.isBlank(chinese)){
            return "";
        }
        char[] clChars = chinese.trim().toCharArray();
        String hanyupinyin = "";
        HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
        // 输出拼音全部大写
        defaultFormat.setCaseType(caseType);
        // 不带声调
        defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        try {
            for (int i = 0; i < clChars.length; i++) {
                String str = String.valueOf(clChars[i]);
                // 如果字符是中文,则将中文转为汉语拼音,并取第一个字母
                if (str.matches("[\u4e00-\u9fa5]+")) {
                    hanyupinyin += PinyinHelper.toHanyuPinyinStringArray(
                            clChars[i], defaultFormat)[0];
                } else if (str.matches("[0-9]+")) {
                    // 如果字符是数字,取数字
                    hanyupinyin += clChars[i];
                } else if (str.matches("[a-zA-Z]+")) {
                    // 如果字符是字母,取字母
                    hanyupinyin += clChars[i];
                } else {
                    // 否则不转换
                }
            }
        } catch (BadHanyuPinyinOutputFormatCombination e) {
            log.error("字符不能转成汉语拼音", e);
        }
        return hanyupinyin;
    }

    /**
     * 获得汉语拼音的首字母（大写）, 标点符号会被剔除
     * @param chinese 要转成拼音的中文
     */
    public static String getFirstLettersUp(String chinese){
        return getFirstLetter(chinese, HanyuPinyinCaseType.UPPERCASE).toUpperCase();
    }

    /**
     * 获得汉语拼音的首字母（小写）, 标点符号会被剔除
     * @param chinese 要转成拼音的中文
     */
    public static String getFirstLettersLow(String chinese){
        return getFirstLetter(chinese, HanyuPinyinCaseType.LOWERCASE).toLowerCase();
    }

    private static String getFirstLetter(String chinese, HanyuPinyinCaseType caseType){
        if(StringUtils.isBlank(chinese)){
            return "";
        }
        char[] clChars = chinese.trim().toCharArray();
        String hanyupinyin = "";

        HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
        defaultFormat.setCaseType(caseType);
        // 不带声调
        defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        try {
            for (int i = 0; i < clChars.length; i++) {
                String str = String.valueOf(clChars[i]);
                if (str.matches("[\u4e00-\u9fa5]+")) {
                    // 如果字符是中文,则将中文转为汉语拼音,并取第一个字母
                    hanyupinyin += PinyinHelper.toHanyuPinyinStringArray(
                            clChars[i], defaultFormat)[0].substring(0, 1);

                } else if (str.matches("[0-9]+")) {
                    // 如果字符是数字,取数字
                    hanyupinyin += clChars[i];
                } else if (str.matches("[a-zA-Z]+")) {
                    // 如果字符是字母,取字母
                    hanyupinyin += clChars[i];
                } else {
                    // 否则不转换

                }
            }
        } catch (BadHanyuPinyinOutputFormatCombination e) {
            log.error("字符不能转成汉语拼音");
        }
        return hanyupinyin;
    }


    /**
     * 获得汉语拼音的首字母（大写）, 保留标点符号
     * @param chinese 要转成拼音的中文
     */
    public static String getFirstLettersIncludeOtherUp(String chinese){
        return getFirstLettersInCLudeOther(chinese ,HanyuPinyinCaseType.UPPERCASE);
    }

    /**
     * 获得汉语拼音的首字母（小写）, 保留标点符号
     * @param chinese 要转成拼音的中文
     */
    public static String getFirstLettersIncludeOtherLow(String chinese){
        return getFirstLettersInCLudeOther(chinese, HanyuPinyinCaseType.LOWERCASE);
    }


    private static String getFirstLettersInCLudeOther(String chinese, HanyuPinyinCaseType caseType) {
        if(StringUtils.isBlank(chinese)){
            return "";
        }
        char[] clChars = chinese.trim().toCharArray();
        String hanyupinyin = "";
        HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
        defaultFormat.setCaseType(caseType);
        // 不带声调
        defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        try {
            for (int i = 0; i < clChars.length; i++) {
                String str = String.valueOf(clChars[i]);
                if (str.matches("[\u4e00-\u9fa5]+")) {
                    // 如果字符是中文,则将中文转为汉语拼音,并取第一个字母
                    hanyupinyin += PinyinHelper.toHanyuPinyinStringArray(clChars[i], defaultFormat)[0].substring(0, 1);
                } else if (str.matches("[0-9]+")) {
                    // 如果字符是数字,取数字
                    hanyupinyin += clChars[i];
                } else if (str.matches("[a-zA-Z]+")) {
                    // 如果字符是字母,取字母
                    hanyupinyin += clChars[i];
                } else {
                    // 否则不转换. 如果是标点符号的话，带着
                    hanyupinyin += clChars[i];
                }
            }
        } catch (BadHanyuPinyinOutputFormatCombination e) {
            log.error("字符不能转成汉语拼音", e);
        }
        return hanyupinyin;
    }


}
